<template>
  <div class="table-container" :class="[className, tableRandom]">
    <!-- 显示表格 -->
    <el-table
      ref="table"
      v-loading="listInfo.loading"
      :max-height="tableHeight"
      :data="data"
      border
      :show-summary="summary"
      :summary-method="getSummaries"
      :row-key="rowKey"
      @current-change="clickRow"
      @select="clickSelect"
      :highlight-current-row="highlightRow"
      @selection-change="handleSelectionChange"
      :span-method="defaultSpanMethod"
      :row-class-name="rowClassName"
    >
      <el-table-column
        v-if="checkBox"
        :reserve-selection="reserveSelection"
        type="selection"
        width="40"
        :selectable="selectable"
      />
      <el-table-column
        v-if="tabIndex"
        :key="'index'"
        align="center"
        fixed="left"
        label="序号"
        :width="fieldList.length === 0 ? '' : 50"
      >
        <template v-slot="scope">
          <span>{{
            scope.$index +
            1 +
            (listInfo.query.curPage - 1) * listInfo.query.pageSize
          }}</span>
        </template>
      </el-table-column>
      <el-table-column
        v-for="(item, index) in fieldList.filter((item) => !item.hidden)"
        :key="index"
        :prop="item.value"
        :label="item.label"
        :fixed="item.fixed"
        :formatter="item.formatter"
        :filters="item.filters"
        :filter-method="item.filterMethod"
        align="center"
        :width="item.width"
        :min-width="item.minWidth || '120px'"
        show-overflow-tooltip
      >
        <template v-if="item.type !== 'column'" v-slot="scope">
          <!-- solt 自定义列-->
          <template v-if="item.type === 'slot'">
            <slot
              :name="'col-' + item.value"
              :row="scope.row"
              :$index="scope.$index"
            />
          </template>
          <!-- 数字输入框带校验规则 -->
          <!--<el-input-number v-else-if="item.type === 'number'"  v-model="scope.row[item.value]" :precision="2"-->
          <!--:min="item.min || 0" :max="item.max || 99999999"/>-->
          <el-form-item
            v-else-if="item.type === 'number'"
            :prop="`data.${scope.$index}[${item.value}]`"
            :rules="item.rules ? item.rules : numberRules"
          >
            <el-input
              type="number"
              style="width: 100px; margintop: 18px"
              v-model.number.trim="scope.row[item.value]"
              :precision="0"
              :min="item.min || 0"
              :step="1"
              v-enterNumber
              :max="item.max || 9999999"
              @input="(e) => (scope.row[item.value] = validSe(e))"
            />
          </el-form-item>
          <!--金额-->
          <el-form-item
            class="input-money"
            v-else-if="item.type === 'money'"
            :prop="`data.${scope.$index}[${item.value}]`"
            :rules="item.rules ? item.rules : moneyRules"
          >
            <el-input
              type="number"
              style="minwidth: 100px; margintop: 18px"
              v-model.number.trim="scope.row[item.value]"
              :precision="0"
              :min="item.min || 0"
              :step="1"
              :max="item.max || 999999999999999"
              @input="(e) => (scope.row[item.value] = validSe(e))"
            >
              <template #append>
                <span v-if="item.unit">{{ item.unit }}</span>
              </template>
            </el-input>
          </el-form-item>
          <!-- 普通输入框 -->
          <el-input
            v-else-if="item.type === 'input'"
            v-model="scope.row[item.value]"
            :maxlength="item.maxlength || 50"
            @input="(e) => (scope.row[item.value] = validSe(e))"
          />
          <!--校验输入框-->
          <el-form-item
            v-else-if="item.type === 'inputRules'"
            :prop="`data.${scope.$index}[${item.value}]`"
            :rules="item.rules ? item.rules : numberRules"
          >
            <el-input
              style="margintop: 18px"
              v-model="scope.row[item.value]"
              :maxlength="item.maxlength || 50"
              @input="(e) => (scope.row[item.value] = validSe(e))"
            />
          </el-form-item>
          <!-- 日期选择框 -->
          <el-date-picker
            v-else-if="item.type === 'date'"
            v-model="scope.row[item.value]"
            value-format="YYYY-MM-DD"
            :disabled-date="
              item.TimePickerOptions && item.TimePickerOptions.disabledDate
            "
          />
          <!-- 下拉选择框 -->
          <select-model
            v-else-if="item.type === 'select-model'"
            v-model="scope.row[item.value]"
            :type-code="item.code"
            :disabled="item.disabled"
            :onlyShowOption="item.onlyShowOption"
            :clearable="item.clearable === false ? item.clearable : true"
            :check-default="item.checkDefault ? item.checkDefault : false"
            :multiple="item.multiple"
          />
          <!-- 标签 -->
          <el-tag v-else-if="item.type === 'tag'">{{
            scope.row[item.value]
          }}</el-tag>
          <!-- 图片 -->
          <!-- v-imgAlart -->
          <img
            v-else-if="item.type === 'image' && scope.row[item.value]"
            height="50px"
            :src="scope.row[item.value]"
          />
          <!-- 其他 -->
          <span v-else>{{
            scope.row[item.value] || scope.row[item.value] === 0
              ? scope.row[item.value]
              : '-'
          }}</span>
        </template>
        <template
          v-if="
            item.type === 'multiHeader' && item.children && item.children.length
          "
        >
          <el-table-column
            v-for="(childItem, childIndex) in item.children"
            :key="childIndex"
            :formatter="childItem.formatter"
            :prop="childItem.value"
            :label="childItem.label"
            align="center"
            :width="childItem.width"
            :min-width="childItem.minWidth || '85px'"
            show-overflow-tooltip
          >
            <template v-if="childItem.type === 'slot'" v-slot="scope">
              <slot
                :name="'col-' + childItem.value"
                :row="scope.row"
                :$index="scope.$index"
              />
            </template>
          </el-table-column>
        </template>
      </el-table-column>
      <el-table-column
        v-if="handle"
        :key="'handle'"
        :fixed="handle.fixed"
        align="center"
        :label="handle.label"
        :width="handle.width"
      >
        <template v-slot="scope">
          <template v-for="(item, index) in handle.btList" :key="index">
            <!-- 自定义操作类型 -->
            <slot
              v-if="item.slot"
              :name="'bt-' + item.name"
              :data="{ item, row: scope.row, $index: scope.$index }"
            />
            <!-- 操作按钮 -->
            <a
              class="actionBtn"
              v-if="
                !item.slot &&
                item.show &&
                (!item.ifRender || item.ifRender(scope.row))
              "
              @click="item.event(scope.row, scope.$index)"
              >{{ item.label }}</a
            >
          </template>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <template v-if="pager">
      <div v-show="!listInfo.loading" class="pagination-container">
        <el-pagination
          :background="true"
          :current-page="listInfo.query.curPage"
          :page-sizes="listInfo.pageSizes"
          :page-size="listInfo.query.pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="listInfo.total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </template>
  </div>
</template>

<script setup name="DialogTable">
import SelectModel from '../SelectModel/index'
import _ from 'lodash'
const { proxy } = getCurrentInstance()
const emits = defineEmits()
const props = defineProps({
  // 自定义类名
  className: {
    type: String,
  },
  // 刷新
  refresh: {
    type: Number,
  },
  // 获取数据的接口
  api: {
    type: Function,
  },
  // 是否显示序号
  tabIndex: {
    type: Boolean,
    default: false,
  },
  // 是否有选择框
  checkBox: {
    type: Boolean,
    default: true,
  },
  rowKey: {
    type: String,
    default: 'id',
  },
  // 选中列表
  checkedList: {
    type: Array,
    default: () => {
      return []
    },
  },
  // 复选框是否可以勾选回调函数
  selectable: {
    type: Function,
  },
  // 单选行
  highlightRow: {
    type: Boolean,
    default: false,
  },
  // 表格字段配置
  fieldList: {
    type: Array,
    default: () => {
      return []
    },
  },
  // 操作栏配置
  handle: {
    type: Object,
  },
  // 是否分页
  pager: {
    type: Boolean,
    default: true,
  },
  // 重置当前页
  initCurpage: {
    type: Number,
  },
  // 查询条件
  query: {
    type: Object,
    default: () => {
      return {}
    },
  },
  // 列表数据
  data: {
    type: Array,
  },
  // 监听高度
  listenHeight: {
    type: Boolean,
    default: true,
  },
  isCompareChecked: {
    //针对selectDepotStorage做兼容
    type: Boolean,
    default: false,
  },
  loadData: {
    type: Boolean,
    default: true,
  },
  spanMethod: {
    type: Function,
  },
  //是否合计数据
  summary: {
    type: Boolean,
    default: false,
  },
  //合计的字段，为空则合计所有数字字段
  summaryFieldList: {
    type: Array,
    default: function () {
      return []
    },
  },
  mergeFiled: {
    type: Array,
    default: function () {
      return []
    },
  },
  mergeData: {
    type: Object,
    default: function () {
      return {}
    },
  },
  reserveSelection: {
    type: Boolean,
    default: false,
  },
  refObj: {
    type: Object,
  },
  rowClassName: {
    type: Function,
  },
})
const tableHeight = ref('355px')
// 列表相关
const listInfo = ref({
  tableHeight: tableHeight.value - 62, // 表格最大高度
  total: 0, // 总条数
  loading: false, // 加载动画
  pageSizes: [10, 20, 50, 100, 300], // 分页数量列表
  query: {
    // 查询条件
    curPage: 1, // 当前页
    pageSize: 20, // 每页条数
  },
})
const tableRandom = ref('tableNum' + Math.random() * 1000)
const numberRules = ref({
  validator: proxy.$validate.positive,
  trigger: 'blur,change',
})
const moneyRules = ref({
  validator: proxy.$validate.positiveMoney,
  trigger: 'blur,change',
})
watch(
  () => props.initCurpage,
  (val) => {}
)
watch(
  () => props.refresh,
  (val) => {
    if (!props.api) return
    getList(props.api)
  },
  {
    immediate: true,
  }
)
watch(
  () => props.data,
  (val) => {
    // 将table实例返回到父级
    emits('update:refObj', proxy.$refs.table)
  },
  {
    deep: true, // 深度监听
  }
)
// 处理参数200
function handleParams() {
  const obj = {}
  for (const key in props.pager) {
    if (
      props.pager[key] ||
      props.pager[key] === 0 ||
      props.pager[key] === false
    ) {
      obj[key] = proxy.$fn.isString(props.pager[key])
        ? proxy.$fn.setTrim(props.pager[key])
        : proxy.$fn.setTrimObj(props.pager[key], key)
    }
  }
  // 如果不需要分页，则无分页相关参数
  return props.pager ? { ...listInfo.value.query, ...obj } : obj
}
function getList(api) {
  // listInfo.value.loading = true
  return new Promise((resolve, reject) => {
    // 每次调用接口时都自动绑定最新的数据
    api(handleParams())
      .then((res) => {
        // listInfo.value.loading = false
        if (res.success) {
          // 使外面可以访问到表格数据
          const arr = Array.isArray(res.data) ? res.data : res.data.result
          emits('update:data', arr)
          if (props.pager) {
            listInfo.value.total = res.total
            listInfo.value.query.curPage = res.curPage - 0
            listInfo.value.query.pageSize = res.pageSize - 0
          }
          // 设置当前选中项
          const rows = arr.filter(
            (row) => props.checkedList.includes(row.id) || row.disabled
          )
          if (rows.length) {
            proxy.$nextTick(() => {
              rows.forEach((row) =>
                proxy.$refs.table.toggleRowSelection(row, true)
              )
            })
          }
          resolve(res)
          emits('handleEvent', 'list', arr)
        } else {
          // proxy.$message({
          //   showClose: true,
          //   message: res.message,
          //   type: "error",
          //   duration: 3500
          // });
          reject()
        }
      })
      .catch(() => {
        reject()
        // listInfo.value.loading = false
      })
  })
}
function handleSizeChange(val) {
  const query = listInfo.value.query
  query.pageSize = val // 每页条数
  query.curPage = 1 // 每页条数切换，重置当前页
  getList(props.api)
}
function handleCurrentChange(val) {
  // proxy.$nextTick(() => {
  //   let fullScreen =
  //     document.getElementsByClassName("box-scroll-y")[0] || "";
  //   if (fullScreen) {
  //     document.getElementsByClassName("box-scroll-y")[0].scrollTop = 0;
  //   } else {
  //     document.getElementsByClassName(
  //       "dialog_full_scroll_y"
  //     )[0].scrollTop = 0;
  //   }
  //   let eltable = document.getElementsByClassName("el-table")[0] || "";
  //   if (eltable) {
  //     document.getElementsByClassName("el-table")[0].scrollTop = 0;
  //   }
  // });
  listInfo.value.query.curPage = val // 当前页
  getList(props.api)
}
// // 派发按钮点击事件
// handleClick(event, data) {
//     emits('handleClick', event, data)
// },
function clickSelect(rows, row) {
  if (props.isCompareChecked) {
    emits('handleEvent', 'compareChecked', { rows: rows, row: row })
  } else {
    emits('handleEvent', 'tableCheckSelect', rows)
  }
}
// 复选框发生变化时触发
function handleSelectionChange(rows) {
  emits('handleEvent', 'tableCheck', rows)
}
// 选中行
function clickRow(row) {
  if (props.highlightRow) {
    emits('handleEvent', 'tableClickRow', row)
  } else {
    return
  }
}
//合计数据
function getSummaries({ columns, data }) {
  const sums = []
  if (props.summaryFieldList.length === 0) return sums
  columns.forEach((column, index) => {
    let arrIndex = -1
    if (typeof props.summaryFieldList[0] === 'string') {
      arrIndex = _.findIndex(props.summaryFieldList, column.property)
    } else if (typeof props.summaryFieldList[0] === 'object') {
      arrIndex = _.findIndex(props.summaryFieldList, function (o) {
        return o.value === column.property
      })
    }
    if (arrIndex !== -1) {
      const values = data.map((item) => Number(item[column.property]))
      if (!values.every((value) => isNaN(value))) {
        sums[index] = values.reduce((prev, curr) => {
          const value = Number(curr)
          if (!isNaN(value)) {
            return proxy.$fn.accAdd(prev, curr)
          } else {
            return prev
          }
        }, 0)
        let formatter = props.summaryFieldList[arrIndex].formatter || ''
        sums[index] = formatter ? formatter(sums[index]) : sums[index]
      } else {
        sums[index] = ''
      }
    }
  })
  if (props.checkBox) {
    sums[1] = '合计'
  } else {
    sums[0] = '合计'
  }
  return sums
}
function defaultSpanMethod({ row, column, rowIndex, columnIndex }) {
  if (spanMethod) {
    return spanMethod({ row, column, rowIndex, columnIndex })
  } else {
    if (props.mergeFiled.length === 0) {
      return [1, 1]
    }
    if (props.mergeFiled.includes(column.property)) {
      const detailCellsMergeData = props.mergeData[row.productId]
      if (detailCellsMergeData) {
        if (rowIndex === detailCellsMergeData.startIndex) {
          return {
            rowspan: detailCellsMergeData.rowspan,
            colspan: 1,
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          }
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
// 自定义表格相关
.table-container {
  //   height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  > .el-table {
    flex: 1;
  }
  > .el-table::before {
    display: none;
  }
  .pagination-container {
    padding: 1px 0;
  }
}
</style>
